# class A:
#
#     def __init__(self,name,age,hobby):
#
#         self.name = name
#         self.age = age
#         self.hobby = hobby
#         # print(111)
#
#     def __len__(self):
#         # print('触发__len__方法')
#         return len(self.__dict__)
# obj = A('MC骚亚伟')

# __len__
# obj = A('MC骚亚伟',18, '抽烟')  #
# ret = len(obj)
# print(ret)
# 一个对象之所以可以使用len()函数,根本原因是这个对象从输入的类中有__len__方法,
# print(ret)
# len('srtfdsf')
# str


# __hash__

# class A:
#
#     pass

# hash(obj) 会调用obj这个对象的类(基类)的__hash__方法
# obj = A()
# print(hash(obj))
# object

# __str__  __repr__ ***


# class Student:
#
#     def __init__(self,name,age,sex):
#         self.name = name
#         self.age = age
#         self.sex = sex
#     #
#
#     def __repr__(self):
#         return f'姓名:{self.name}年龄:{self.age}性别:{self.sex}'
#
#     def __str__(self):
#         return f'姓名:{self.name}年龄:{self.age}性别:{self.sex}666'
#
# obj = Student('小智', 18, '男')
# obj1 = Student('dj智', 18, '男')
# obj2 = Student('mc智', 18, '男')
#
# # print(str(obj))
# # print(str(obj))  # 会触发__str__
# # print(obj)  # 打印输出实例会触发__str__
# # print(obj1)
# # print(obj2)
# # print('此对象为%s' %obj)  # 格式化输出会触发__str__
# # print(obj)  # 触发__repr__
# print('此对象是%r' %obj)  # 触发__repr__
#
# # print(obj) 先触发__str__方法


# __call__方法
# class A:
#     def __init__(self):
#         self.a = 1
#         print(111)
#
#     def __call__(self, *args, **kwargs):
#         print(666)
#
# obj = A()
# obj()


# class A:
#     def __init__(self):
#         self.a = 1
#         self.b = 2
#
#     def __eq__(self,obj):
#         print(111)
#         return True
#         # if  self.a == obj.a and self.b == obj.b:
#         #     return True
# a = A()
# b = A()
# print(a == b)  # 对一个类的两个对象进行比较操作,就会触发__eq__方法

# __del__ 析构方法
# class A:
#
#     def __del__(self):
#         print(111)
#
# obj = A()
# del obj
#  l1 = [1,2,3]
# dic = {1:2}
# del l1
# del dic  # 主动删除
# # print(dic)
# print(111)
# print(222)

# __new__ 构造方法
# __new__创造并返回一个新对象.


# class A(object):
#
#     def __init__(self):
#         print('in __init__')
#
#     def __new__(cls, *args, **kwargs):
#         # print(cls)  # A
#         print('in __new__')
#         object1 = object.__new__(cls)
#         return object1
# obj = A()
# 类名() 先触发__new__ 并且将类名自动传给cls.
# print(obj)

# 单例模式

# 一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象.
# class A:
#     pass
# obj = A()
# obj1 = A()
# obj2 = A()
# print(obj,obj1,obj2)

# 面试几乎都会让你手写一个单例模式

# 这个类的对象不是个性化的,主要是实例化对象之后去执行类中的方法.
# class A:
#     __instance = None
#
#     def __new__(cls, *args, **kwargs):
#         if not cls.__instance:
#             object1 = object.__new__(cls)
#             cls.__instance = object1
#         return cls.__instance
#
#
# obj = A()
# obj1 = A()
# obj2 = A()
# print(obj,obj1,obj2)

# __item__

# 对对象进行类似于字典的操作
#
# class Foo:
#     def __init__(self, name):
#         self.name = name
#
#     def __getitem__(self, item):
#         print(item)
#         print('get时 执行我')
#
#     def __setitem__(self, key, value):
#         self.name = value
#         print('set时执行我')
#
#     def __delitem__(self, key):
#         print(f'del obj{[key]}时,我执行')
#
# obj = Foo('御姐')
# # obj.__dict__
# # obj['name']
# # obj['name'] = '萝莉'
# # print(obj.name)
# del obj['name']

# __enter__ __exit__

# class A:
#     def __init__(self,name):
#         self.name = name
#
#     def __enter__(self):
#         print(111)
#
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print(222)
#
# # obj = A('mc小龙')
#
# # 对一个对象类似于进行with语句上下文管理的操作, 必须要在类中定义__enter__ __exit__
# with A('mc小龙') as obj:
#     print(555)
# # print(obj.name)


# class A:
#
#     def __init__(self, text):
#         self.text = text
#
#     def __enter__(self):  # 开启上下文管理器对象时触发此方法
#         self.text = self.text + '您来啦'
#         return self  # 将实例化的对象返回f1
#
#     def __exit__(self, exc_type, exc_val, exc_tb):  # 执行完上下文管理器对象f1时触发此方法
#         self.text = self.text + '这就走啦'
#
# # f1 = A('大爷')
# with A('大爷') as f1:
#     print(f1.text)
# print(f1.text)
